package day12;

import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

//a.银行账户余额查询与转账,使用ReentrantReadWriteLock实现银行账户系统，
// 支持并发余额查询但互斥转账操作  (提示: 提供三个方法 查询(读锁)  存款(写锁)  取款(写锁))
public class Bank {
    double money=1000;//存款
    ReentrantReadWriteLock rwLock=new ReentrantReadWriteLock();
    public void select(){
        String name=Thread.currentThread().getName();
        rwLock.readLock().lock();
        try {
            Thread.sleep(1000);
            System.out.println(name+"查询出余额"+money);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            rwLock.readLock().unlock();
        }
    }
   public void deposit(double num){
        //写 存款
       String name=Thread.currentThread().getName();
       rwLock.writeLock().lock();
       try {
           money+=num;
           Thread.sleep(1000);
           System.out.println(name+"存了"+num+"余额"+money);
       } catch (InterruptedException e) {
           e.printStackTrace();
       } finally {
           rwLock.writeLock().unlock();
       }
   }
    public void withdraw(double num){
        //写 取款
        String name=Thread.currentThread().getName();
        rwLock.writeLock().lock();
        try {
            if(money<num){
                System.out.println(name+"余额不足");
            }
            money-=num;
            Thread.sleep(1000);
            System.out.println(name+"取了"+num+"余额"+money);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public static void main(String[] args) {
        String name=Thread.currentThread().getName();
        Random r=new Random();
        Bank b=new Bank();
        for(int i=0;i<3;i++){
                new Thread(() -> {
                    for(int j=0;j<5;j++) {
                        int n=r.nextInt(3);//0-2
                        System.out.println(n);
                        switch (n){
                            case 0:b.select(); break;
                            case 1:b.deposit(r.nextInt(100)); break;
                            case 2:b.withdraw(r.nextInt(300)); break;
                        }
                    }
                }, "线程" + i).start();

        }
    }
}
